import { ref, computed, reactive, onMounted, onUnmounted, readonly } from 'vue'
import { ElMessage } from 'element-plus'
import request from '@/utils/request'

// 下载状态枚举
enum DownloadStatus {
  IDLE = 'idle',
  PREPARING = 'preparing',
  DOWNLOADING = 'downloading',
  PAUSED = 'paused',
  COMPLETED = 'completed',
  FAILED = 'failed',
  CANCELLED = 'cancelled'
}

// 下载会话接口
interface DownloadSession {
  downloadId: string
  fileId: number
  fileName: string
  fileSize: number
  downloadedBytes: number
  progress: number
  speed: number
  status: DownloadStatus
  startTime: number
  lastUpdateTime: number
  controller?: AbortController
  chunks: Uint8Array[]
}

export function useFileDownload() {
  // 状态管理
  const isDownloading = ref(false)
  const downloadSessions = reactive<Map<string, DownloadSession>>(new Map())
  const activeSessionId = ref<string | null>(null)

  // 存储键
  const STORAGE_KEY = 'rickpan_download_sessions'

  /**
   * 创建下载会话
   */
  const createDownloadSession = (fileId: number, fileName: string, fileSize: number): DownloadSession => {
    const downloadId = `download_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
    
    const session: DownloadSession = {
      downloadId,
      fileId,
      fileName,
      fileSize,
      downloadedBytes: 0,
      progress: 0,
      speed: 0,
      status: DownloadStatus.PREPARING,
      startTime: Date.now(),
      lastUpdateTime: Date.now(),
      chunks: []
    }

    downloadSessions.set(downloadId, session)
    activeSessionId.value = downloadId
    saveSessionsToStorage()
    
    return session
  }

  /**
   * 使用fetch实现流式下载
   */
  const downloadFileWithProgress = async (
    fileId: number,
    fileName: string,
    fileSize?: number
  ): Promise<void> => {
    const session = createDownloadSession(fileId, fileName, fileSize || 0)

    try {
      session.status = DownloadStatus.DOWNLOADING
      session.controller = new AbortController()
      isDownloading.value = true

      // 构建流式下载URL（不触发浏览器下载）
      const token = localStorage.getItem('token')
      const downloadUrl = `http://localhost:8080/api/files/${fileId}/stream`

      const response = await fetch(downloadUrl, {
        method: 'GET',
        headers: {
          'Authorization': `Bearer ${token}`,
          'Cache-Control': 'no-cache'
        },
        signal: session.controller.signal
      })

      if (!response.ok) {
        throw new Error(`下载失败: ${response.status} ${response.statusText}`)
      }

      // 获取文件大小
      const contentLength = response.headers.get('content-length')
      if (contentLength && !session.fileSize) {
        session.fileSize = parseInt(contentLength, 10)
      }

      // 如果仍然没有文件大小，设置为未知大小模式
      if (!session.fileSize) {
        session.fileSize = -1 // -1表示未知大小
      }

      // 检查是否支持流式读取
      if (!response.body) {
        throw new Error('浏览器不支持流式下载')
      }

      const reader = response.body.getReader()
      const chunks: Uint8Array[] = []

      while (true) {
        const { done, value } = await reader.read()

        if (done) break

        // 检查是否被取消
        if (session.status === DownloadStatus.CANCELLED) {
          reader.cancel()
          break
        }

        // 检查是否被暂停
        if (session.status === DownloadStatus.PAUSED) {
          reader.cancel()
          break
        }

        chunks.push(value)
        session.chunks = chunks
        session.downloadedBytes += value.length

        // 更新进度
        updateDownloadProgress(session)
      }

      // 下载完成，创建文件并触发下载
      if (session.status === DownloadStatus.DOWNLOADING) {
        const blob = new Blob(chunks)
        const url = window.URL.createObjectURL(blob)

        const link = document.createElement('a')
        link.href = url
        link.download = fileName
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        window.URL.revokeObjectURL(url)

        session.status = DownloadStatus.COMPLETED
        session.progress = 100

        // 创建下载传输记录
        await createDownloadTransferRecord(session)

        ElMessage.success(`文件下载完成: ${fileName}`)

        // 延迟清理会话
        setTimeout(() => {
          downloadSessions.delete(session.downloadId)
          if (activeSessionId.value === session.downloadId) {
            activeSessionId.value = null
          }
          saveSessionsToStorage()
        }, 3000)
      }

    } catch (error: any) {
      console.error('下载失败:', error)

      if (error.name === 'AbortError') {
        session.status = DownloadStatus.CANCELLED
        ElMessage.warning(`下载已取消: ${fileName}`)
      } else {
        session.status = DownloadStatus.FAILED
        ElMessage.error(`下载失败: ${fileName} - ${error.message}`)
      }
    } finally {
      isDownloading.value = false
      saveSessionsToStorage()
    }
  }

  /**
   * 创建下载传输记录
   */
  const createDownloadTransferRecord = async (session: DownloadSession) => {
    try {
      await request.post('/transfer/records', {
        sessionId: session.downloadId,
        fileName: session.fileName,
        originalName: session.fileName,
        fileSize: session.fileSize,
        transferType: 'DOWNLOAD',
        transferStatus: 'COMPLETED',
        progressPercentage: 100,
        transferredBytes: session.downloadedBytes,
        startTime: new Date(session.startTime).toISOString().slice(0, -1),
        endTime: new Date().toISOString().slice(0, -1)
      })
      console.log('下载传输记录已创建:', session.fileName)
    } catch (error) {
      console.error('创建下载传输记录失败:', error)
      // 不影响下载功能，只是记录失败
    }
  }

  /**
   * 更新下载进度
   */
  const updateDownloadProgress = (session: DownloadSession) => {
    const now = Date.now()
    const timeDiff = (now - session.lastUpdateTime) / 1000

    // 计算进度
    if (session.fileSize > 0) {
      session.progress = Math.min(100, Math.round((session.downloadedBytes / session.fileSize) * 100))
    } else if (session.fileSize === -1) {
      // 未知文件大小，显示已下载的字节数
      session.progress = 0 // 不显示百分比进度
    }

    // 计算下载速度（每秒更新一次）
    if (timeDiff >= 1) {
      const lastChunkSize = session.chunks[session.chunks.length - 1]?.length || 0
      session.speed = Math.round(lastChunkSize / timeDiff)
      session.lastUpdateTime = now
    }
  }

  /**
   * 暂停下载
   */
  const pauseDownload = (sessionId: string) => {
    const session = downloadSessions.get(sessionId)
    if (session && session.status === DownloadStatus.DOWNLOADING) {
      session.status = DownloadStatus.PAUSED
      session.controller?.abort()
      saveSessionsToStorage()
      ElMessage.info(`已暂停下载: ${session.fileName}`)
    }
  }

  /**
   * 恢复下载
   */
  const resumeDownload = async (sessionId: string) => {
    const session = downloadSessions.get(sessionId)
    if (!session || session.status !== DownloadStatus.PAUSED) {
      throw new Error('无效的下载会话或状态')
    }

    try {
      session.status = DownloadStatus.DOWNLOADING
      session.controller = new AbortController()

      const token = localStorage.getItem('token')
      const downloadUrl = `http://localhost:8080/api/files/${session.fileId}/stream`
      
      // 使用Range请求实现断点续传
      const response = await fetch(downloadUrl, {
        method: 'GET',
        headers: {
          'Authorization': `Bearer ${token}`,
          'Range': `bytes=${session.downloadedBytes}-`,
          'Cache-Control': 'no-cache'
        },
        signal: session.controller.signal
      })

      if (!response.ok && response.status !== 206) {
        throw new Error(`恢复下载失败: ${response.status}`)
      }

      if (!response.body) {
        throw new Error('浏览器不支持流式下载')
      }

      const reader = response.body.getReader()

      while (true) {
        const { done, value } = await reader.read()
        
        if (done) break
        
        if (session.status === DownloadStatus.CANCELLED || session.status === DownloadStatus.PAUSED) {
          reader.cancel()
          break
        }

        session.chunks.push(value)
        session.downloadedBytes += value.length
        updateDownloadProgress(session)
      }

      // 下载完成处理
      if (session.status === DownloadStatus.DOWNLOADING) {
        const blob = new Blob(session.chunks)
        const url = window.URL.createObjectURL(blob)

        const link = document.createElement('a')
        link.href = url
        link.download = session.fileName
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        window.URL.revokeObjectURL(url)

        session.status = DownloadStatus.COMPLETED
        session.progress = 100
        
        ElMessage.success(`文件下载完成: ${session.fileName}`)
        
        setTimeout(() => {
          downloadSessions.delete(session.downloadId)
          if (activeSessionId.value === session.downloadId) {
            activeSessionId.value = null
          }
          saveSessionsToStorage()
        }, 3000)
      }

    } catch (error: any) {
      console.error('恢复下载失败:', error)
      session.status = DownloadStatus.FAILED
      ElMessage.error(`恢复下载失败: ${session.fileName}`)
    } finally {
      saveSessionsToStorage()
    }
  }

  /**
   * 取消下载
   */
  const cancelDownload = (sessionId: string) => {
    const session = downloadSessions.get(sessionId)
    if (session) {
      session.status = DownloadStatus.CANCELLED
      session.controller?.abort()
      
      downloadSessions.delete(sessionId)
      if (activeSessionId.value === sessionId) {
        activeSessionId.value = null
      }
      
      saveSessionsToStorage()
      ElMessage.warning(`已取消下载: ${session.fileName}`)
    }
  }

  /**
   * 格式化速度显示
   */
  const formatSpeed = (bytesPerSecond: number): string => {
    if (bytesPerSecond < 1024) return `${bytesPerSecond} B/s`
    if (bytesPerSecond < 1024 * 1024) return `${(bytesPerSecond / 1024).toFixed(1)} KB/s`
    return `${(bytesPerSecond / (1024 * 1024)).toFixed(1)} MB/s`
  }

  /**
   * 保存会话到本地存储
   */
  const saveSessionsToStorage = () => {
    try {
      const sessionsData = Array.from(downloadSessions.entries()).map(([id, session]) => ({
        id,
        session: {
          ...session,
          controller: undefined, // 不保存AbortController
          chunks: [] // 不保存chunks数据
        }
      }))
      localStorage.setItem(STORAGE_KEY, JSON.stringify(sessionsData))
    } catch (error) {
      console.error('保存下载会话失败:', error)
    }
  }

  /**
   * 从本地存储恢复会话
   */
  const loadSessionsFromStorage = () => {
    try {
      const stored = localStorage.getItem(STORAGE_KEY)
      if (stored) {
        const sessionsData = JSON.parse(stored)
        
        for (const { id, session } of sessionsData) {
          // 只恢复未完成的会话，并设置为暂停状态
          if (session.status === DownloadStatus.DOWNLOADING) {
            session.status = DownloadStatus.PAUSED
          }
          
          if (session.status !== DownloadStatus.COMPLETED && session.status !== DownloadStatus.CANCELLED) {
            downloadSessions.set(id, session)
          }
        }
      }
    } catch (error) {
      console.error('恢复下载会话失败:', error)
    }
  }

  /**
   * 清理本地存储
   */
  const clearSessionsStorage = () => {
    localStorage.removeItem(STORAGE_KEY)
  }

  /**
   * 获取所有下载会话
   */
  const getAllSessions = () => {
    return Array.from(downloadSessions.values())
  }

  /**
   * 获取下载统计信息
   */
  const getDownloadStats = () => {
    const sessions = Array.from(downloadSessions.values())
    return {
      total: sessions.length,
      downloading: sessions.filter(s => s.status === DownloadStatus.DOWNLOADING).length,
      paused: sessions.filter(s => s.status === DownloadStatus.PAUSED).length,
      completed: sessions.filter(s => s.status === DownloadStatus.COMPLETED).length,
      failed: sessions.filter(s => s.status === DownloadStatus.FAILED).length,
      cancelled: sessions.filter(s => s.status === DownloadStatus.CANCELLED).length
    }
  }

  // 计算属性
  const currentSession = computed(() => {
    return activeSessionId.value ? downloadSessions.get(activeSessionId.value) : null
  })

  const downloadProgress = computed(() => {
    return currentSession.value?.progress || 0
  })

  const downloadSpeed = computed(() => {
    return currentSession.value?.speed || 0
  })

  // 生命周期管理
  onMounted(() => {
    loadSessionsFromStorage()
  })

  onUnmounted(() => {
    saveSessionsToStorage()
  })

  return {
    // 状态
    isDownloading: readonly(isDownloading),
    downloadProgress,
    downloadSpeed,
    currentSession,
    downloadSessions: readonly(downloadSessions),
    activeSessionId: readonly(activeSessionId),

    // 方法
    downloadFileWithProgress,
    pauseDownload,
    resumeDownload,
    cancelDownload,
    getAllSessions,
    getDownloadStats,
    formatSpeed,

    // 存储管理
    saveSessionsToStorage,
    loadSessionsFromStorage,
    clearSessionsStorage
  }
}
